package top.h1234.codesandbox.utils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StopWatch;
import top.h1234.codesandbox.model.ExecuteMessage;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 进程工具类
 */
public class ProcessUtils {

    /**
     * 获取进程输出信息
     *
     * @param process 进程
     * @param opsType 操作类型
     * @return 进程输出信息
     */
    public static ExecuteMessage getProcessOutputMessage(Process process, String opsType) {
        // 返回结果对象
        ExecuteMessage executeMessage = new ExecuteMessage();
        try {
            // 开始计时
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            // 等待编译/运行完成，获取退出码
            int exitValue = process.waitFor();
            executeMessage.setExitValue(exitValue);
            // 判断编译/运行是否成功
            if (exitValue == 0) {
                System.out.println(opsType + "成功");
                // 获取正常输出结果
                List<String> outputList = getOutputList(process);
                executeMessage.setMessage(StringUtils.join(outputList, "\n"));
            } else {
                System.out.println(opsType + "失败，错误码为：" + exitValue);
                // 获取正常输出结果
                List<String> outputList = getOutputList(process);
                executeMessage.setMessage(StringUtils.join(outputList, "\n"));
                // 获取错误输出结果
                List<String> errorOutputList = getErrorOutputList(process);
                executeMessage.setErrorMessage(StringUtils.join(errorOutputList, "\n"));
            }
            // 结束计时
            stopWatch.stop();
            // 统计耗时
            long lastTaskTimeMillis = stopWatch.getLastTaskTimeMillis();
            executeMessage.setTime(lastTaskTimeMillis);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return executeMessage;
    }

    /**
     * 获取正常输出结果
     *
     * @param process 进程对象
     * @return 正常输出结果
     */
    private static List<String> getOutputList(Process process) throws IOException {
        // 获取输出结果（Java进程的输出结果是写到输入流中，并且也是从输入流中读取）
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        // 用于拼接输出结果
        List<String> outputStrList = new ArrayList<>();
        // 逐行读取输出信息
        String compileOutputLine;
        while ((compileOutputLine = bufferedReader.readLine()) != null) {
            // 拼接输出结果
            outputStrList.add(compileOutputLine);
        }
        return outputStrList;
    }

    /**
     * 获取错误输出结果
     *
     * @param process 进程对象
     * @return 错误输出结果
     */
    private static List<String> getErrorOutputList(Process process) throws IOException {
        // 获取错误输出结果（Java进程的输出结果是写到输入流中，并且也是从输入流中读取）
        BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        // 用于拼接输出结果
        List<String> errorOutputStrList = new ArrayList<>();
        // 逐行读取错误输出结果
        String errorCompileOutputLine;
        while ((errorCompileOutputLine = errorBufferedReader.readLine()) != null) {
            // 拼接错误输出结果
            errorOutputStrList.add(errorCompileOutputLine);
        }
        return errorOutputStrList;
    }

}
